class MessagelessRetrievalContext(object):
    def __enter__(self):
        return None
    
    def __exit__(self, exc_type, exc_value, traceback):
        pass

class MessageRetrievalContext(object):
    def __init__(self, msg, on_completion):
        self.msg = msg
        self.on_completion = on_completion

    def __enter__(self):
        return self.msg

    def __exit__(self, exc_type, exc_value, traceback):
        if exc_type == None:
            self.on_completion(self.msg)

class ITransport(object):
    def add_queue(self, queue_name):
        """Add a new queue to the system with the given name.

        queue_name:
            Name of new queue to create.

        """
        raise NotImplementedError()

    def subscribe(self, queue_name, message_type):
        """Subscribe queue_name to the message type message_type.

        queue_name:
            queue to route any message recieved as a result of this
            subscription.

        message_type:
            The type of message we're subscribing to.

        Will start directing all messages of type message_type to the queue
        queue_name.
        """
        raise NotImplementedError()

    def send(self, msg):
        """Send a message.

        msg:
            The message object to send.

        """
        raise NotImplementedError()

    def retrieve(self, queue_name):
        """Create a context that can delimit the message's retrieval.

        queue_name:
            The name of the queue to fetch the next message from.

        Returns a context manager object that manages a message that should be
        handled. When done handling the message, the manager should be exited.
        The message might be None, which indicates that no message is currently
        in the queue.
        """
        raise NotImplemenetedError()

    def close(self):
        """Perform closing procedues. """
        pass
